package com.xbongbong.crm.perform.query.list.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmListQryService;
import com.xbongbong.crm.handle.analysis.ContractListAnalysisDataHandler;
import com.xbongbong.crm.perform.query.list.button.ArchivedTag;
import com.xbongbong.crm.perform.query.list.button.Remind;
import com.xbongbong.crm.service.condition.ContractConditionServiceImpl;
import com.xbongbong.crm.service.impl.ContractLinkProductServiceImpl;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.explain.HandleExplainHelp;
import com.xbongbong.parent.pojo.list.ConditionListPojo;
import com.xbongbong.parent.pojo.list.ConditionListResultPoJo;
import com.xbongbong.parent.pojo.list.DataAnalysisListPojo;
import com.xbongbong.parent.pojo.list.FieldListPojo;
import com.xbongbong.parent.pojo.list.PermissionListPojo;
import com.xbongbong.parent.util.FieldUtil;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.message.model.PushModel;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.TabConstant;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.TagEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.help.SaasLinkProductHelp;
import com.xbongbong.saas.service.toolbox.help.SaasListDataPermissionHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;

/**
 * @author 吴峰
 * @date 2022/05/13 10:10
 */
@Service("contractListServiceImpl")
@Slf4j
public class ContractListServiceImpl extends AbstractCrmListQryService {


    @Resource
    private ContractConditionServiceImpl contractConditionService;
    @Resource
    private SaasListDataPermissionHelp saasListDataPermissionHelp;
    @Resource
    private ContractLinkProductServiceImpl contractLinkProductService;
    @Resource
    private SaasLinkProductHelp saasLinkProductHelp;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private HandleExplainHelp handleExplainHelp;
    @Resource
    private ContractListAnalysisDataHandler contractListAnalysisDataHandler;
    @Resource
    private PushModel pushModel;
    @Resource
    private Remind remind;


    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.CONTRACT.getCode());
    }

    @Override
    public List<ConditionsEntityExt> getPermission(PermissionListPojo permissionListPojo) throws XbbException {
        UserVO userVO = permissionListPojo.getUserVO();
        List<ConditionsEntityExt> conditionList = new ArrayList<>();
        if (userVO.isMaxDataPermission()){
            return conditionList;
        }

       return getTeamUserPermission(userVO);
    }

    /**
     * 需要根据字段返回字段类型
     * 合同订单范围筛选可选择负责人、协同人，签订人，其中负责人和协同人在调用该方法层已实现，此处无需实现，除非有特殊逻辑
     * @param attr
     * @return
     */
    @Override
    protected Integer getFieldTypeByAttr(String attr) {
        if (Objects.equals(attr, FieldTypeEnum.OWNERID.getAlias())) {
            return FieldTypeEnum.OWNERID.getType();
        }  else if (Objects.equals(attr, FieldTypeEnum.COUSERID.getAlias())) {
            return FieldTypeEnum.COUSERID.getType();
        } else if (Objects.equals(attr, ContractEnum.SIGN_PERSON.getAttr())) {
            return ContractEnum.SIGN_PERSON.getFieldType();
        }
        return 0;
    }

    @Override
    public ConditionListResultPoJo getCondition(ConditionListPojo conditionListPojo) throws XbbException {
        getCommonConditionList(conditionListPojo);
        // 公共筛选
        webCommonFilter(conditionListPojo);
        return new ConditionListResultPoJo(conditionListPojo.getConditionList(), conditionListPojo.getShouldConditionList());
    }


    private List<ConditionsEntityExt> getCommonConditionList(ConditionListPojo conditionListPojo) throws XbbException {

        List<ConditionsEntityExt>  list = contractConditionService.handleConditionBySubBusinessType(conditionListPojo);
        conditionListPojo.getConditionList().addAll(list);
        setCommonCondition(conditionListPojo);
        // 关联产品筛选
        saasLinkProductHelp.selectProductCondition(conditionListPojo.getConditionList(), conditionListPojo.getCorpid());

        return conditionListPojo.getConditionList();
    }

    @Override
    public ConditionListResultPoJo mobileGetCondition(ConditionListPojo conditionListPojo) throws XbbException {
        //  手机端条件封装
        saasListDataPermissionHelp.dingtalkRangeScreen(conditionListPojo.getConditionList(), conditionListPojo.getUserVO(), XbbRefTypeEnum.CONTRACT.getCode(), conditionListPojo.getSubBusinessType(), conditionListPojo.getPlatform());
        // 公共条件封装
        getCommonConditionList(conditionListPojo);
        return new ConditionListResultPoJo(conditionListPojo.getConditionList(), conditionListPojo.getShouldConditionList());
    }

    @Override
    public HandleExplainPojo getExplain(FieldListPojo fieldListPojo) throws XbbException {
        String corpid = fieldListPojo.getCorpid();
        Integer saasMark = fieldListPojo.getSaasMark();
        List<String> fieldList = new ArrayList<>();
        Boolean isJxcUse = paasAppModel.validateAppEnable(null, XbbRefTypeEnum.JXC.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        List<FieldAttrEntity> explainList = commonGetExplain(fieldListPojo, fieldList);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(JSONArray.toJSONString(explainList));
        if (!isJxcUse) {
            explainList.remove(explainMap.get(ContractEnum.SHIP_STATUS.getAttr()));
            explainMap.remove(ContractEnum.SHIP_STATUS.getAttr());
            if (explainMap.containsKey(ContractEnum.PRODUCT.getAttr())) {
                FieldAttrEntity productField = explainMap.get(ContractEnum.PRODUCT.getAttr());
                if (Objects.nonNull(productField.getSubForm()) && Objects.nonNull(productField.getSubForm().getItems())) {
                    Iterator iterator = productField.getSubForm().getItems().iterator();
                    while (iterator.hasNext()) {
                        FieldAttrEntity fieldAttr = JSONObject.parseObject(JSONObject.toJSONString(iterator.next()), FieldAttrEntity.class);
                        if ((Objects.equals(fieldAttr.getAttr(), SelectProductEnum.OUTSTOCK_NUM.getAttr()) || Objects.equals(fieldAttr.getAttr(), SelectProductEnum.WAIT_OUTSTOCK_NUM.getAttr()) || Objects.equals(fieldAttr.getAttr(), SelectProductEnum.RETURN_NUM.getAttr()))) {
                            iterator.remove();
                        }
                    }
                }
            }
        }
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO(explainList, fieldListPojo.getForm(), fieldListPojo.getCorpid(), fieldListPojo.getUserVO().getUserId(), fieldListPojo.getUserVO(), true, fieldListPojo.getSubBusinessType());
        HandlerExplainVO handlerExplainVO = handleExplainHelp.handleExplain(handlerExplainDTO);
        HandleExplainPojo handleExplainPojo = new HandleExplainPojo();
        explainList = handlerExplainVO.getHeadList();
        handleExplainPojo.setFieldList(fieldList);
        handleExplainPojo.setExplainList(explainList);

        return handleExplainPojo;
    }

    @Override
    public List<PaasFormDataEntityExt> webDataAnalysis(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        try {
            String corpid = dataAnalysisListPojo.getCorpid();
            List<PaasFormDataEntityExt> formDataList = dataAnalysisListPojo.getFormDataList();

            FormDataListDTO formDataListDTO = new FormDataListDTO(corpid, dataAnalysisListPojo.getFormId(), dataAnalysisListPojo.getSaasMark(), dataAnalysisListPojo.getBusinessType(), dataAnalysisListPojo.getSubBusinessType(), dataAnalysisListPojo.getDistributorMark(), dataAnalysisListPojo.getUserVO(), dataAnalysisListPojo.getAnalysisAmountOfThousandBitsWithOriginalValue());
            PaasFormDataEsListVO formDataListVO = new PaasFormDataEsListVO();
            formDataListVO.setPaasFormDataESList(formDataList);
            List<FieldAttrEntity> explainList = dataAnalysisListPojo.getExplainList();
            // 合同特殊逻辑 将合同订单中应收、未收与合同金额可见权限一致
            explainList = ContractListAnalysisDataHandler.setAmountVisible(explainList);
            formDataListVO.setHeadList(explainList);

            // 解析关联产品，只有web需要
            contractLinkProductService.analysisListProductData(formDataListDTO, formDataListVO.getPaasFormDataESList(), formDataListVO.getHeadList(), 1, null);
            contractListAnalysisDataHandler.analysisDataList(formDataListDTO, formDataListVO);
            contractListAnalysisDataHandler.analysisAmountOfThousandBits(formDataListVO, dataAnalysisListPojo.getAnalysisAmountOfThousandBitsWithOriginalValue());
            return formDataListVO.getPaasFormDataESList();
        } catch (Exception e) {
            log.error("com.xbongbong.crm.list.ContractListServiceImpl.dataAnalysis error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public List<PaasFormDataEntityExt> dingtalkDataAnalysis(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        try {
            List<PaasFormDataEntityExt> formDataList = dataAnalysisListPojo.getFormDataList();

            FormDataListDTO formDataListDTO = new FormDataListDTO(dataAnalysisListPojo.getCorpid(), dataAnalysisListPojo.getFormId(), dataAnalysisListPojo.getSaasMark(), dataAnalysisListPojo.getBusinessType(), dataAnalysisListPojo.getSubBusinessType(), dataAnalysisListPojo.getDistributorMark(), dataAnalysisListPojo.getUserVO(), dataAnalysisListPojo.getAnalysisAmountOfThousandBitsWithOriginalValue());

            PaasFormDataEsListVO formDataListVO = new PaasFormDataEsListVO();
            formDataListVO.setHeadList(dataAnalysisListPojo.getExplainList());
            formDataListVO.setForm(dataAnalysisListPojo.getForm());
            formDataListVO.setPaasFormDataESList(formDataList);
            contractListAnalysisDataHandler.analysisDataList(formDataListDTO, formDataListVO);
            contractListAnalysisDataHandler.analysisAmountOfThousandBits(formDataListVO, false);
            // 摘要和标题的封装
            formDataListVO = ExplainUtil.getValueByData(formDataListVO, formDataListDTO.getFormMap(), dataAnalysisListPojo.getFormIdAndHeadListMap());
            return formDataListVO.getPaasFormDataESList();
        } catch (Exception e) {
            log.error("com.xbongbong.crm.list.ContractListServiceImpl.dingtalkDataAnalysis error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    protected void handleFieldAttrEntity(FieldAttrEntity item, FieldListPojo fieldListPojo) {
        super.handleFieldAttrEntity(item, fieldListPojo);
        FieldUtil.packageSelectProductField(item);
    }

    @Override
    public List<AppListPojo> dingtalkOperate(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        String corpid = dataAnalysisListPojo.getCorpid();
        List<AppListPojo> appListPojos = new ArrayList<>();

        List<PaasFormDataEntityExt> dataList =dataAnalysisListPojo.getFormDataList();
        Integer businessType = dataAnalysisListPojo.getBusinessType();
        List<Long> dataIdIn = new ArrayList<>();
        dataList.forEach(item->{
            dataIdIn.add(item.getId());
        });
        FieldAttrEntity contactAmountExplain = null;
        for (FieldAttrEntity item : dataAnalysisListPojo.getExplainList()) {
            if (Objects.equals(item.getAttr(), ContractEnum.AMOUNT.getAttr())) {
                contactAmountExplain = item;
                break;
            }
        }
        boolean amountVisible = false;
        if (contactAmountExplain != null && Objects.equals(contactAmountExplain.getVisible(), 1)) {
            amountVisible = true;
        }
        // 提醒
        Remind remindPojo = remind.setRemindField( corpid, businessType, dataAnalysisListPojo.getSubBusinessType(), dataIdIn, dataAnalysisListPojo.getExplainList());
        for (PaasFormDataEntityExt contractEntity : dataList) {
            JSONObject data = contractEntity.getData();
            Long contractId = contractEntity.getDataId();
            String searNo = contractEntity.getSerialNo() == null ? "" : contractEntity.getSerialNo();
            Long appId = contractEntity.getAppId();
            Long menuId = contractEntity.getMenuId();
            Long formId = contractEntity.getFormId();
            Integer isRed = getIntegerOrDefaultFromFormData(data, ContractEnum.IS_RED.getAttr(), 0);
            String amount = FastJsonHelper.getStringOrDefaultFromFormData(data, ContractEnum.AMOUNT.getAttr(), "0");

            String unit = I18nMessageUtil.getMessage(TabConstant.YUAN);
            amount += unit;
            if (!amountVisible) {
                amount = StringConstant.INVISIBLE_VALUE;
            }

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();

            /*-- 角标 -*/
            superScript.put("message", remindPojo.getList().contains(contractId) ? 1 : 0);
            // 归档标志：1代表归档，2代表未归档
            if (Objects.equals(data.getInteger(ContractEnum.ARCHIVED.getAttr()), 1)) {
                superScript.put("archived", 1);
            }
            /*-- 标签 -*/

            /*-- 其他 -*/
            others.put("amount", amount);
            others.put("isRed", isRed);

            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<SummaryDataPoJo> lablesList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            // 进行了退货退款的合同塞一个标签(退货合同)
            //是否包含红冲合同（即是否为退货合同）
            Integer hasRed = getIntegerOrDefaultFromFormData(data, ContractEnum.HAS_RED.getAttr(), 0);
            if (Objects.equals(hasRed, 1)) {
                SummaryDataPoJo dataPoJo = new SummaryDataPoJo();
                String name = I18nMessageUtil.getMessage(I18nStringConstant.RETURN_CONTRACT);
                dataPoJo.setAttr("");
                dataPoJo.setType("red");
                dataPoJo.setAttrName(name);
                dataPoJo.setFieldType(3);
                List<Object> objectList = new ArrayList<>();
                Object obj = name;
                objectList.add(obj);
                dataPoJo.setValue(objectList);
                lablesList.add(0, dataPoJo);
            }
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);
            //app系统关联数据展示需要 others 和 superScript
            data.put("others", others);
            data.put("superScript", superScript);

            appListPojos.add(new AppListPojo(contractId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId));
        }
        return appListPojos;
    }

    @Override
    public void webOperate(DataAnalysisListPojo dataAnalysisListPojo) throws XbbException {
        String corpid = dataAnalysisListPojo.getCorpid();
        Integer businessType = dataAnalysisListPojo.getBusinessType();
        List<PaasFormDataEntityExt> dataList =dataAnalysisListPojo.getFormDataList();
        List<FieldAttrEntity> list = dataAnalysisListPojo.getExplainList();
        List<Long> dataIdIn = new ArrayList<>();
        dataList.forEach(item->{
            dataIdIn.add(item.getId());
        });
        // 提醒
        Remind remindPojo = remind.setRemindField(corpid,  businessType, dataAnalysisListPojo.getSubBusinessType(), dataIdIn, list);
        String field = ContractEnum.CONTRACT_NO.getAttr();
        ArchivedTag archivedTagPojo = new ArchivedTag(field+"Tag");
        dataAnalysisListPojo.getExplainList().forEach(item->{
            if (Objects.equals(item.getAttr(), field)) {
                item.setTagAttr(field + "Tag");
            }
        });
        dataList.forEach(item->{

            // 提醒
            Remind.setRemindData(remindPojo, item);

            JSONObject tagData = item.getTagData();
            JSONObject data = item.getData();
            // 设置“归档”状态
            ArchivedTag.setArchivedData(archivedTagPojo, tagData, Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) && Objects.equals(data.getInteger(ContractEnum.ARCHIVED.getAttr()), 1), TagEnum.TAG_ARCHIVED_CONTRACT);

        });
    }
}
